/*
 * @author jjophin
 */

var GeoMap = function(options){
    this.mapContainer = this.getElement(options.mapContainer);
	this.paletteContainer = options.paletteContainer && this.getElement(options.paletteContainer);
    this.currentRegion = options.defaultRegion || "world";
	this.currentColor = options.color || [0xF4CCCC,0x990000];
	this.height = options.height || "347px";
    this.width = options.width || "556px";
	this.delimiter = options.delimiter || "~";
	options.drawPalette && this._drawPalette();
	this.currentResolution = (this.currentRegion== "world" ? "regions":"markers");
	this.showZoomOut = (this.currentRegion== "world" ? false:true);
	this.geoMap = new google.visualization.GeoMap(this.mapContainer);
	this.dataCache = {};
	this.dataTable = new google.visualization.DataTable();	
   	this.dataTable.addColumn('string', 'Location');
   	this.dataTable.addColumn('number', 'Number');	
    this.zoomToCountries = options.zoomToCountries || false;
	if(this.zoomToCountries){
		this.zoomHandler = options.zoomHandler;
		var clickHandler = this._generateClickHandler();
		google.visualization.events.addListener(this.geoMap , "regionClick", clickHandler);	
		google.visualization.events.addListener(this.geoMap , "zoomOut", clickHandler);	
	}	
};

GeoMap.prototype = (function(){
    var getElement = function(id){
        return id.constructor == String ? document.getElementById(id) : id;
    };
	
	var draw = function(dataObj){
		this.currentKey = (dataObj && dataObj.key) || "defaultKey";
		var currentCacheKey = this.currentRegion + this.currentKey;
		dataObj && dataObj.location && dataObj.location != "" && _setData.call(this, dataObj, currentCacheKey);
		if(!this.dataCache[currentCacheKey])
			return false;		
		this.dataTable.removeRows(0, this.dataTable.getNumberOfRows());
		this.dataTable.addRows(this.dataCache[currentCacheKey]);
		this.geoMap.draw(this.dataTable, {
			region : this.currentRegion,
			width : this.width,
			height : this.height,
			colors : this.currentColor,
			showZoomOut : this.showZoomOut,
			dataMode : this.currentResolution
		});
		return true;
	}
	
	var isCached = function(region, key){
		return this.dataCache[region + (key ||this.currentKey)] ? true:false;
	}

	var setRegion = function(region, dataObj){
		this.showZoomOut = (region == "world" ?false:true); 
		this.currentResolution = (region == "world" ? "regions":"markers");
		this.currentRegion = region;
		this.draw(dataObj);
	}

    var clearCache = function(){
        this.dataCache = {};
    }
	
	var _setData = function(dataObj, currentCacheKey){
		var mapData = [[dataObj.location.split(this.delimiter), dataObj.count.split(this.delimiter)],[]];
		for(var j=0; j<mapData[0][0].length; j++){
                    mapData[1][j] = [];
                    mapData[1][j] = [mapData[0][0][j], Number(mapData[0][1][j])];
                }
		this.dataCache[currentCacheKey] = mapData[1];
	}
	
	var _generateClickHandler = function(){
		var that =this;
		return function(e){
			if(e.region && e.region.length != "2")		//to avoid clicks on provinces
				return;
			that.currentRegion = e.region || "world";
			that.currentResolution = (that.currentRegion == "world" ? "regions":"markers");
			that.showZoomOut = (that.currentRegion == "world" ? false:true);
			that.zoomHandler(that.currentRegion);
		}		
	}
	
	var _drawPalette = function(){
		var colorData = [["0xF4CCCC", "0x990000"], ["0xFCE5CD", "0xB45F06"], ["0xFFF2CC", "0xBF9000"], ["0xD9EAD3", "0x38761D"], ["0xD0E0E3", "0x134F5C"], ["0xCFE2F3", "0x0B5394"], ["0xD9D2E9", "0x351C75"], ["0xEAD1DC", "0x741B47"]];
		this.paletteContainer.style.height = "25px";
		for (var i = 0; i < colorData.length; i++) {
			var currColumn = _createTag(this.paletteContainer, i, "div");
			_setCss([currColumn], [{
				width : "25px", 
				height : "25px", 
				cssFloat : "right",			//for Mozilla
				styleFloat : "right",		//for IE
				border : "2px solid #ffffff",
				backgroundColor : colorData[i][1].replace("0x","#"),
				cursor : "hand"
			}]);
			currColumn.onclick = (function(that, colorArr){
				return function(e){
					e = e || window.event;
					that.currentColor = colorArr[e.srcElement.id];
					that.draw({key : that.currentKey});
				};
			})(this, colorData);
		}
	}
	
	var _createTag = function(parent, id, type){
    	var newChild = document.createElement(type);
    	newChild.id = id;
    	parent.appendChild(newChild);
    	return newChild;
	}
	
	var _setCss = function(tag, propertyArr){
    	for(var i in tag)
        	for(var j in propertyArr[i])
            	tag[i].style[j] = propertyArr[i][j];	
	}	
	
	return {
		getElement : getElement,
		isCached : isCached,
        clearCache : clearCache,
		draw : draw,
		setRegion : setRegion,
		_drawPalette : _drawPalette,
		_generateClickHandler : _generateClickHandler
	}	
})();